package com.cg.bank.web.action;

import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.upload.FormFile;

import com.cg.bank.domain.User;
import com.cg.bank.service.ManagerImpl;
import com.cg.bank.service.ManagerInterface;
import com.cg.tools.JavaMail;
import com.cg.tools.Utils;
import com.cg.vcode.VeriftyCode;

/**
 * UserAction模块
 * <p>
 * 用于管理用户信息所有请求
 * </p>
 * 
 * @author chunges
 * @date 2018年8月30日 上午9:13:52
 * @version V1.0
 */

public class UserAction extends BaseAction {
	private static final String SYSTEMMAIL= "YOURQQ";
	private static final String SYSTEMMAILAUTHCODE= "YOURTOKEN";
	/**
	 * 验证码
	 */
	private final String VERIFTYCODE = "veriftyCode";
	/**
	 *  检查表单模式-登录(0)
	 */
	protected static final int CHECKLOGIN = 0;
	/**
	 *  检查表单模式-注册(1)
	 */
	protected static final int CHECKREGISTER = 1;
	/**
	 *  检查表单模式-修改信息(2)
	 */
	protected static final int CHECKUPDATEUSER = 2;
	
	/**
	 * 找不到对应Action将前往首页
	 */
	@Override
	protected ActionForward unspecified(ActionMapping mapping, ActionForm form, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		return mapping.findForward("index");
	}
	
	/**
	 * 登录Action
	 * 
	 * @param mapping actionMapping
	 * @param form 表单bean
	 * @param request request请求
	 * @param response response
	 */
	public ActionForward login(ActionMapping mapping, ActionForm form, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		User formUser = (User) form;
		// 检查表单数据
		Map<String, String> errorMap = checkForm(formUser, request, CHECKLOGIN);
		if (errorMap == null || errorMap.size() <= 0) {
			ManagerInterface manager = ManagerImpl.getInstance();
			User user = manager.login(formUser);
			HttpSession session = request.getSession();
			// 保存用户登录信息
			session.setAttribute(USERSESSIONFLAG, user);
			// 用于开启管理员权限操作
			if (ROOTACCOUNT.equals(formUser.getAccount())) {
				request.getSession().setAttribute("isRoot", 1);
			}
			// 构建回文账户
			createSafeAccount(user.getAccount(), response);
			session.removeAttribute(VERIFTYCODE);
			return mapping.findForward("personalHome");
		}
		// 校检表单信息失败
		request.setAttribute("errors", errorMap);
		return mapping.findForward("loginForward");
	}

	/**
	 * 注册Action
	 * 
	 * @param mapping actionMapping
	 * @param form 表单bean
	 * @param request request请求
	 * @param response response
	 */
	public ActionForward register(ActionMapping mapping, ActionForm form, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
        User userForm = (User) form;
        System.out.println(userForm);
        // 检查表单数据
        Map<String, String> errorMap = checkForm(userForm, request, CHECKREGISTER);
        if (errorMap == null || errorMap.size() <= 0) {
        	// 注册成功
            ManagerInterface manager = ManagerImpl.getInstance();
            manager.register(userForm);
        } else {
        	// 校检表单信息失败
        	//request.setAttribute("errors", errorMap);
        	response.getWriter().write(new String(errorMap.toString().getBytes("UTF-8")));
        	System.out.println(errorMap);
		}
        return null;
        //return mapping.findForward("register");
	}
	
	/**
	 * 上传头像Action
	 * 
	 * @param mapping actionMapping
	 * @param form 表单bean
	 * @param request request请求
	 * @param response response
	 */
	public ActionForward uploadImage(ActionMapping mapping, ActionForm form, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		// 检查文件大小---格式(getType) 压缩文件
		User uploadForm = (User) form;
		FormFile formFile = uploadForm.getFormFile();
		// 截取文件名后缀
		int endMark = formFile.getFileName().lastIndexOf(".");
		if (endMark != -1) {
			String fileSuffix = formFile.getFileName().substring(endMark);
			String filePath = request.getServletContext().getRealPath("/resource/user/images/");
			// 创建文件输出流写入头像,文件名为当前时间
			FileOutputStream out = new FileOutputStream(filePath + System.currentTimeMillis() + fileSuffix);
			out.write(formFile.getFileData());
			out.close();
		}
		return mapping.findForward("updateUser");
	}
	
	/**
	 * 验证码Action
	 * 
	 * @param mapping actionMapping
	 * @param form 表单bean
	 * @param request request请求
	 * @param response response
	 */
	public ActionForward verifty(ActionMapping mapping, ActionForm form, HttpServletRequest request, 
			HttpServletResponse response) throws Exception {
		VeriftyCode veriftyCode = new VeriftyCode();
        // 生成验证码
        BufferedImage bufferedImage = veriftyCode.getImage();
        // 保存验证码至session
        request.getSession().setAttribute(VERIFTYCODE, veriftyCode.getText());
        // 将验证码保存到response
        VeriftyCode.output(bufferedImage, response.getOutputStream());
        return null;
	}
	
	/**
	 * 邮箱验证码Action
	 * 
	 * @param mapping actionMapping
	 * @param form 表单bean
	 * @param request request请求
	 * @param response response
	 */
	public ActionForward getMailVeriftyCode(ActionMapping mapping, ActionForm form, HttpServletRequest request, 
			HttpServletResponse response) throws Exception {
		String userMail = request.getParameter("mail");
		if(userMail != null) {
			response.setHeader("Content-Type", "text/text");
			/*Cookie cookie = new Cookie("getMailTime", String.valueOf(System.currentTimeMillis()));
			response.addCookie(cookie);*/
			String regex = "^([a-z0-9A-Z]+[-|_|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
			if (!userMail.matches(regex)) {
				// 邮箱格式校检失败
				response.getOutputStream().print("errorMailFormate");
			} else {
				// 发送电子邮件到用户邮箱
				try {
					String mailVeriftyCode = Utils.getRandomString(6);
					JavaMail mail = new JavaMail(SYSTEMMAIL, SYSTEMMAILAUTHCODE);
					mail.setDebug(true);
					mail.sendMail("【CG银行】", "验证码:" + mailVeriftyCode + ",请尽快完成注册", userMail);
					// 将验证码保存到用户session
					request.getSession().setAttribute(VERIFTYCODE, mailVeriftyCode);
					response.getOutputStream().print("success");
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		return null;
	}
	
	
	/**
	 * 找回密码Action
	 * 
	 * @param mapping actionMapping
	 * @param form 表单bean
	 * @param request request请求
	 * @param response response
	 */
	public ActionForward getPassword(ActionMapping mapping, ActionForm form, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		
		return null;
	}

	/**
	 * 更新用户信息Action
	 * 
	 * @param mapping actionMapping
	 * @param form 表单bean
	 * @param request request请求
	 * @param response response
	 */
	public ActionForward updateUserInformation(ActionMapping mapping, ActionForm form, HttpServletRequest request,
		HttpServletResponse response) throws Exception {
	    User userForm =(User) form;
        // 检查表单数据
        Map<String, String> errorMap = checkForm(userForm, request, CHECKUPDATEUSER);
        if (errorMap == null || errorMap.size() <= 0) {
            ManagerInterface manager = ManagerImpl.getInstance();
            User user = (User) request.getSession().getAttribute(USERSESSIONFLAG);
            userForm.setId(user.getId());
            manager.updateUserInformation(userForm);
            request.setAttribute("msg", "修改资料成功:)");
            // 修改了密码时  注销用户Session 此处可用异步提交,提示信息后跳转
            request.getSession().invalidate();
        } else {
        	// 修改失败(校检表单信息失败)
        	request.setAttribute("errors", errorMap);
        }
        return mapping.findForward("updateUser");
	}

	/**
	 * 下线Action
	 * 
	 * @param mapping actionMapping
	 * @param form 表单bean
	 * @param request request请求
	 * @param response response
	 */
	public ActionForward logout(ActionMapping mapping, ActionForm form, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		ManagerInterface manager = ManagerImpl.getInstance();
		HttpSession session = request.getSession();
		User user = (User) session.getAttribute(USERSESSIONFLAG);
		manager.logout(user);
		// 注销session
		session.invalidate();

		return mapping.findForward("loginRedirect");
	}

	/**
	 * 注销用户信息Action
	 * 
	 * @param mapping actionMapping
	 * @param form 表单bean
	 * @param request request请求
	 * @param response response
	 */
	public ActionForward logoff(ActionMapping mapping, ActionForm form, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		HttpSession session = request.getSession();
		User user = (User) session.getAttribute(USERSESSIONFLAG);
        ManagerImpl.getInstance().logoffAccount(user);
        request.setAttribute("msg", user.getAccount() + " 已注销,24小时内可恢复,期待再次遇见您 :)");
        session.invalidate();
        
        return mapping.findForward("index");
	}

	/**
	 * 创建安全账户名(构建回文用户名)
	 * 
	 * @param account 需要构建的账户名
	 * @param resp request请求
	 */
	private void createSafeAccount(String account, HttpServletResponse resp) {
		// 从第三个数字截取到倒数第二位并用*代替
		Cookie cookie = new Cookie("account", account.replaceAll(account.substring(3, 9), "******"));
		resp.addCookie(cookie);
	}
	
	 /**
     * 表单参数校检
     *
     * @param req  request
     * @param form 表单参数
     * @return errorMap 错误信息Map
     */
    private Map<String, String> checkForm(User form, HttpServletRequest req, int veriftyModel) {
    	Map<String, String> errorMap = new HashMap<>();
    	// 密码检查
    	String password = form.getPassword();
    	if (password == null || password.trim().isEmpty()) {
    		errorMap.put("password", "密码为空");
    	} else if (password.length() < 4 || password.length() > 32) {
    		errorMap.put("password", "密码格式必须在4~18位之间");
    	}
    	// 注册/登录检查
    	if (veriftyModel != 2) {
    		// 检查账户
    		String account = form.getAccount();
    		String regex = "^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$";
    		if (account == null || account.trim().isEmpty()) {
    			errorMap.put("account", "请输入账户");
    		} else if (!account.matches(regex)) {
    			errorMap.put("account", "账户名格式错误");
    		}
    		// 检查验证码
	        if (!checkVeriftyCode(req)) {
	            errorMap.put(VERIFTYCODE, "验证码错误");
	        }
	        // 注册/登录验证结束
	        return errorMap;
		}
    	// 修改用户信息检查
    	if (veriftyModel == 2) {
    		// 用户名检查
            String userName = form.getUserName();
            if (userName == null || userName.trim().isEmpty()) {
                errorMap.put("userName", "昵称为空");
            } else if (userName.length() >= 12) {
                errorMap.put("userName", "昵称不允许超出12个字");
            } 
            // 年龄检查
            int age = form.getAge();
            if (age <= 0 || age > 120) {
                errorMap.put("age", "年龄格式错误");
            }
            // 性别检查
            String sex = form.getSex();
            if (sex == null || sex.trim().isEmpty()) {
                errorMap.put("sex", "性别为空");
            }
            // 修改用户信息需要将信息更新到session
    		User user = (User) req.getSession().getAttribute(USERSESSIONFLAG);
    		user.setUserName(userName);
    		user.setSex(sex);
    		user.setAge(age);
    		req.getSession().setAttribute(USERSESSIONFLAG,user);
    	}
        
        return errorMap;
    }
    
    /**
     * 检查验证码
     *
     * @param req request
     * @return result 检查结果
     */
    private boolean checkVeriftyCode(HttpServletRequest req) {
    	HttpSession session = req.getSession();
    	String veriftyCode= (String) session.getAttribute(VERIFTYCODE);
		if (veriftyCode == null) {
			return false;
		}
    	
		// session中的验证码和表单中的验证码做匹配
		return veriftyCode.equalsIgnoreCase(req.getParameter(VERIFTYCODE));
    }
    
}